package com.runewbie.pafcmall.product;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * 1、整合Mybatis-Plus
 *      1）、导入依赖
 *         <dependency>
 *             <groupId>com.baomidou</groupId>
 *             <artifactId>mybatis-plus-boot-starter</artifactId>
 *             <version>3.2.0</version>
 *         </dependency>
 *      2）、配置
 *          1、配置数据源
 *              1）、导入数据库的驱动
 *              2）、在application.yml中配置数据源信息
 *          2、配置Mybatis-Plus
 *              1）、使用@MapperScan扫描mapper接口
 *              2）、告诉Mybatis-Plus，sql映射文件位置
 *
 * 2、逻辑删除
 *  1）、配置全局的逻辑删除规则（可省略）
 *  2）、配置逻辑删除组件的Bean（可省略）
 *  3）、给Bean加上逻辑删除注解@TableLogic
 *
 * 3、JSR303数据校验
 *  1）、配置校验：给Bean标注校验注解，注解位于：javax.validation.constraints，并定义自己的 message 提示
 *  2）、开启校验：在需要校验的方法的对象上使用 @Valid 注解
 *      效果：校验错误后会有默认的响应
 *  3）、获取校验结果：给校验结果的bean后紧跟一个 BindingResult ，就可以获取到校验的结果
 *  4）、分组校验：(多场景的复杂校验)
 *  有时候我们提交的数据，在新增的时候不需要校验，在更新的时候需要校验，比如用户id，这个是时候我们就可以使用分组校验来区分
 *      1、在Bean中给校验注解标注什么情况下需要进行校验：
 *          @NotBlank(message = "品牌名不能为空", groups = {AddGroup.class, UpdateGroup.class})
 *          注意：没有标注分组的，在校验的时候不会起作用
 *      2、在Controller上对需要校验的方法使用 @Validated 注解，标记分组: @Validated({AddGroup.class}
 *      3、默认没有指定分组的校验注解 @NotNull、@NotBlank等，在分组校验情况下不生效，只会在 @Valid下生效
 *  5）、自定义校验：
 *      1、编写一个自定义的校验注解
 *      2、编写一个自定义的校验器
 *      3、关联 自定义的校验注解 和 自定义的校验器
 *          @Documented
 *          @Constraint(
 *              validatedBy = {ListValueConstraintValidator.class[可以指定多个不同的校验器，适配不同类型的校验]} // 关联 自定义的校验注解 和 自定义的校验器
 *          )
 *          @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
 *          @Retention(RetentionPolicy.RUNTIME)
 *          public @interface ListValue
 *
 *
 *  4、统一异常处理：@ControllerAdvice、@RestControllerAdvice
 *   1）、编写异常处理类，使用@ControllerAdvice 或 @RestControllerAdvice
 *   2）、使用@ExceptionHandler标注方法可以处理的异常
 *
 *  5、配置模板引擎
 *   1）、开发期间配置在yml文件中配置 thymeleaf-starter：关闭缓存
 *   2）、静态资源都放在static文件夹下，就可以按照路径直接访问
 *   3）、页面放在 thymeleaf 下，直接访问
 *      SpringBoot在项目访问的时候，默认会找index.html文件来进行渲染，Springboot将mvc的默认配置都放在了 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration 类中
 *   4）、页面修改不重启服务器实时更新
 *      1）、引入dev-tools依赖
 *      2）、修改完页面要重新编译所修改的页面 使用 ctrl + shift + F9；如果是类或者代码配置，还是推荐重启服务，因为有时候可能会有问题
 *
 *  6、整合reids
 *   1）、引入starter-data-redis
 *   2）、简单配置redis的host等信息
 *   3）、使用SpringBoot自动配置的StringRedisTemplate来操作redis
 *    redis——>map；存放数据key，数据值value
 *
 *  7、整合redisson作为分布式锁的功能框架
 *   1）、引入依赖
 *         <dependency>
 *             <groupId>org.redisson</groupId>
 *             <artifactId>redisson</artifactId>
 *             <version>3.12.5</version>
 *         </dependency>
 *   2）、配置redisson
 *
 *  8、整合 SpringCache 简化缓存开发
 *   1）、引入依赖
 *      spring-boot-starter-cache、spring-boot-starter-data-redis（使用redis作为缓存就要引入redis的依赖）
 *   2）、写配置
 *      （1）、自动配置了那些？
 *          org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration 缓存自动配置类
 *          org.springframework.boot.autoconfigure.cache.CacheProperties 所有在xml文件中配置的属性都封装在这里
 *          org.springframework.boot.autoconfigure.cache.CacheConfigurations 获取每一种类型的缓存
 *          org.springframework.boot.autoconfigure.cache.CacheConfigurations#getConfigurationClass 得到对应缓存的映射
 *          org.springframework.boot.autoconfigure.cache.CacheType 一个枚举类，封装了各种类型的缓存
 *          org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration 使用redis作为缓存时的各种配置
 *
 *          CacheAutoConfiguration 会导入 RedisCacheConfiguration
 *          RedisCacheConfiguration 会自动装配好了redis缓存管理器 RedisCacheManager
 *      （2）、我们自己需要配置的内容：配置使用redis作为缓存
 *          spring.cache.type=redis
 *   3）、测试使用缓存
 *      @Cacheable: Triggers cache population. 触发缓存保存
 *      @CacheEvict: Triggers cache eviction. 触发删除缓存
 *      @CachePut: Updates the cache without interfering with the method execution. 更新缓存，而不影响方法的执行
 *      @Caching: Regroups multiple cache operations to be applied on a method. 重新组合要在一个方法上应用的多个缓存操作
 *      @CacheConfig: Shares some common cache-related settings at class-level. 在类级别共享一些与缓存相关的常见设置
 *      （1）、开启缓存功能：@EnableCaching
 *      （2）、只需要使用注解就能完成缓存操作
 *   4）、原理
 *      CacheAutoConfiguration --> RedisCacheConfiguration --自动配置了-->
 *      RedisCacheManager --初始化所有的缓存(按照配置文件中配置的缓存名来确定)-->
 *      每个缓存决定使用什么配置 --> 如果 org.springframework.data.redis.cache.RedisCacheConfiguration 有就用已有的，没有就用默认陪配置
 *      --> 想改缓存配置，只需要容器中放一个 RedisCacheConfiguration 即可 --> 就会应用到当前 RedisCacheManager 管理的所有缓存分区中
 *
 *
 *
 *
 *
 * @EnableFeignClients(basePackages = "com.runewbie.pafcmall.product.feign") 开启远程服务调用，basePackages 也可以省略不写，
 * 如果当前类在另一个子包下则需要明确使用 basePackages
 */

@EnableFeignClients(basePackages = "com.runewbie.pafcmall.product.feign")
@EnableDiscoveryClient
@MapperScan("com.runewbie.pafcmall.product.dao")
@SpringBootApplication
public class PafcmallProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(PafcmallProductApplication.class, args);
    }

}
